package com.ruibo.tax.mq.receive;


import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ruibo.tax.constants.ReceiveDataPackageConstants;
import com.ruibo.tax.constants.SendDataPackageConstants;
import com.ruibo.tax.constants.TaxConstants;
import com.ruibo.tax.model.base.PackageHead;
import com.ruibo.tax.model.base.XMLEncodeModel;
import com.ruibo.tax.model.dz.HZDZXX;
import com.ruibo.tax.model.dz.HZDZXXXMLEncodeModel;
import com.ruibo.tax.model.dz.SSDZXX;
import com.ruibo.tax.model.dz.SSDZXXXMLEncodeModel;
import com.ruibo.tax.model.log.TaxSendLog;
import com.ruibo.tax.model.log.TaxSummaryReceiptLog;
import com.ruibo.tax.mq.send.ReconciliationSendZIPMessage;
import com.ruibo.tax.repository.TaxSendLogRepository;
import com.ruibo.tax.repository.TaxSummaryReceiptLogRepository;
import com.ruibo.tax.service.HBJHHBCFService;
import com.ruibo.tax.service.HBJHJCZDJCService;
import com.ruibo.tax.service.HBJHXKZJBXXService;
import com.ruibo.tax.utils.XMLUtils;
import com.ruibo.tax.utils.ZipUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.ArrayList;


import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;


/**
 * @description: 税务对环保的对账
 * @author: 孙 峰
 * @time: 2020/10/19 10:33
 */
@Slf4j
@Component
public class DZQLSW2HBTask {


    //    税务对环保的对账队列
    @Resource(name = "DZ_QLSW2HB")
    MQQueue dz_sw2hbMQQueue;

    @Autowired
    private ReconciliationSendZIPMessage reconciliationSendZIPMessage;

    //    排污许可
    @Autowired
    private HBJHXKZJBXXService hbjhxkzjbxxService;

    //    自动监测
    @Autowired
    private HBJHJCZDJCService hbjhjczdjcService;
    //    环保处罚
    @Autowired
    private HBJHHBCFService hbjhhbcfService;

    @Autowired
    private XMLUtils xmlUtils;

    @Autowired
    private TaxSummaryReceiptLogRepository taxSummaryReceiptLogRepository;

    @Autowired
    private TaxSendLogRepository taxSendLogRepository;

    /**
     * 获取税务对账信息
     * 1、此处包括实时对账以及汇总对账  需要分开处理对账逻辑
     * <p>
     * 2、原先是采用这种方式   现在改成监听队列获取数据  DZSW2HBMQListener
     */
    public void receiveMsgDZQLSW2HB() {
        ByteArrayInputStream bis = null;
        try {
            // 获取对账队列中所有数据   处理对账信息
            int currentDepth = dz_sw2hbMQQueue.getCurrentDepth();
            if (currentDepth <= 0) {
                log.info("暂无对账信息");
                return;
            }
            log.info("对账队列的深度为,{}", currentDepth);
            // 获取所有对账信息
            for (int i = 0; i < currentDepth; i++) {
                MQMessage retrievedMessage = new MQMessage();
                dz_sw2hbMQQueue.get(retrievedMessage);
                int messageLength = retrievedMessage.getMessageLength();
                log.info("获取到对账数据的长度为,{}", messageLength);
                byte[] msgData = new byte[messageLength];
                retrievedMessage.readFully(msgData);

                RandomAccessFile accessFile = new RandomAccessFile(new File("c:/b.zip"), "rw");
                accessFile.write(msgData, 0, messageLength);
                accessFile.close();
                readZipFile("c:/b.zip");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.toString());
        }
    }

    /**
     * 处理对账的文件处理
     *
     * @param filePath
     * @throws Exception
     */
    public void readZipFile(String filePath) throws Exception {
        //String filePath = ”文件的绝对路径“;
        ZipFile zf = new ZipFile(filePath);
        Enumeration zipEnum = zf.entries();
        while (zipEnum.hasMoreElements()) {
            ZipEntry ze = (ZipEntry) zipEnum.nextElement();
            if (ze.isDirectory()) {
                //为空的文件夹什么都不做
            } else {
                if (ze.getSize() > 0) {
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(zf.getInputStream(ze), "GBK"));
                    String line;
                    while ((line = br.readLine()) != null) {
                        log.info("接受的数据为:{}", line);
                        // 处理接受的数据
                        JAXBContext jaxbContext = JAXBContext.newInstance(XMLEncodeModel.class);
                        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
                        StringReader stringReader = new StringReader(line);
                        XMLEncodeModel xmlEncodeModel = (XMLEncodeModel) jaxbUnmarshaller.unmarshal(stringReader);
                        //1、 对接受的数据生成文件保存
                        xmlUtils.creteFile(line, xmlEncodeModel);
                        //2、保存数据
                        // 获取heads。根据heads不同的类型 创建不同的数据解析模型
                        PackageHead heads = xmlEncodeModel.getHeads();
                        // 需要从heads里面获取需要处理的数据包类型
                        String sjblx = heads.getSJBLX();
                        //处理实时对账的逻辑
                        if (ReceiveDataPackageConstants.SSDZXX.equals(sjblx)) {
                            handlerSSDZXX(line);
                        } else if (ReceiveDataPackageConstants.HZDZXX.equals(sjblx)) {
                            handlerHZDZXX(line);
                        }
                    }
                    br.close();
                }
            }
        }
        zf.close();
    }

    /**
     * 处理实时对账
     *
     * @param line
     * @throws JAXBException
     */
    private void handlerSSDZXX(String line) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(SSDZXXXMLEncodeModel.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        StringReader str = new StringReader(line);
        SSDZXXXMLEncodeModel ssdzxxxmlEncodeModel = (SSDZXXXMLEncodeModel) unmarshaller.unmarshal(str);
        SSDZXX roots = ssdzxxxmlEncodeModel.getRoots();
        // 处理实时对账的逻辑   // 根据发送的报名和包类型 更新 sendStatus
        taxSendLogRepository.updateSendStatusByAndPkg_numAndPkg_type(TaxConstants.RECEIPT_STATUS, roots.getSJBBH(), roots.getSJBLX());
        // 处理汇总对账信息
    }

    /**
     * 处理汇总对账
     *
     * @param line
     * @throws JAXBException
     */
    private void handlerHZDZXX(String line) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(HZDZXXXMLEncodeModel.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        StringReader str = new StringReader(line);
        HZDZXXXMLEncodeModel hzdzxxxmlEncodeModel = (HZDZXXXMLEncodeModel) unmarshaller.unmarshal(str);
        List<HZDZXX> roots = hzdzxxxmlEncodeModel.getRoots();
        ArrayList<TaxSummaryReceiptLog> summaryReceiptLogs = new ArrayList<>();
        roots.forEach(hzdzxx -> {
            // 处理实时对账的逻辑
            TaxSummaryReceiptLog summaryReceiptLog = new TaxSummaryReceiptLog();
            summaryReceiptLog.setPkg_type(hzdzxx.getSJBLX());
            summaryReceiptLog.setPkg_num(hzdzxx.getSJBBH());
            summaryReceiptLog.setUuid(hzdzxx.getUUID());
            summaryReceiptLog.setStatus(TaxConstants.ACTIVE);
            summaryReceiptLog.setCreateAt(LocalDateTime.now());
            summaryReceiptLog.setUpdateAt(LocalDateTime.now());
            summaryReceiptLogs.add(summaryReceiptLog);
            // 跟新数据ReceiptStatus
            if (SendDataPackageConstants.PWXKZB.equals(hzdzxx.getSJBLX())) {
                hbjhxkzjbxxService.updateReceiptStatusByUUID(TaxConstants.SEND, hzdzxx.getUUID());
            } else if (SendDataPackageConstants.ZDJCXX.equals(hzdzxx.getSJBLX())) {
                hbjhjczdjcService.updateReceiptStatusByUUID(TaxConstants.SEND, hzdzxx.getUUID());
            } else if (SendDataPackageConstants.HBCFXX.equals(hzdzxx.getSJBLX())) {
                hbjhhbcfService.updateReceiptStatusByUUID(TaxConstants.SEND, hzdzxx.getUUID());
            }
            log.info("处理数据成功");
        });
        // 保存汇总对账信息
        taxSummaryReceiptLogRepository.saveAll(summaryReceiptLogs);
    }


}
